#pragma once

#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<cstring>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void writer(int wfd) //父进程写
{
    int cnt = 0;
    char str[128] = "hello, I am father!";
    while(1)
    {
        char buffer[128]; 
        snprintf(buffer, sizeof(buffer), "%s, cnt: %d, id: %d", str, cnt, getpid());   
        write(wfd, buffer, strlen(buffer));
        sleep(1);
        cnt++;
        // char c = 'A';
        // write(wfd, &c, sizeof(c)); 
        // printf("pipe number:%d\n", cnt++); //测试管道在内核内存中维护的缓冲区大小,64kb
    }
    //close(wfd); //情况3：不再写入数据，且关闭写端fd
}

void reader(int rfd)  //子进程读
{
    int cnt = 5;
    while(cnt--)
    {
        char buffer1[128];
        int n = read(rfd, buffer1, sizeof(buffer1));
        //if(n > 0)
             printf("child get messages: %s\n", buffer1);
        // else if(n == 0)  //情况3：读端会将管道内部剩余的数据读完，最后会读取到返回值为0，表示读结束，类似于读到了文件结尾
        // {
        //     printf("write close, read ending, quit....\n");
        //     break;
        // }
        // else 
        // {
        //     printf("read error\n");
        //     break;
        // }
        //sleep(100);  //情况2:管道内部被写满，且(子进程)未关闭读端fd，(父进程)写端就要阻塞等待，直到管道内部有空间
    }
    close(rfd);
}

int main()
{
    //1.父进程创建管道
    int pipefd[2];
    int n = pipe(pipefd);
    if(n == -1) return 1;

    //2.父进程创建子进程
    pid_t id = fork();
    if(id == 0)
    {
        //子进程关闭写，进行读
        close(pipefd[1]);
        reader(pipefd[0]);
    }
    //父进程关闭读，进行写
    close(pipefd[0]);
    writer(pipefd[1]);

    return 0;
}
